<?php

namespace think\wework\Command;

use think\Wework;
use think\facade\Log;
use think\facade\Cache;
use think\console\Input;
use think\console\Output;
use think\console\Command;
use think\console\input\Option;
use think\console\input\Argument;
use Symfony\Component\Process\Process;
use Symfony\Component\Process\PhpExecutableFinder;

class BotListen extends Command
{
    protected function configure()
    {
        $this->setName('webot:listen')->setDescription("启动机器人监听程序");
    }

    protected function execute(Input $input, Output $output)
    {
        $botList = [];
        $redis = Cache::store('redis')->handler();
        while (true) {
            $token = $redis->rPop(Wework::BotTokenListKey);
            if ($token) {
                if (empty($botList[$token])) {
                    Log::bot("运行虚拟客户端：$token");
                    $process = $this->_makeBotProcess($token);
                    $process->start();
                } else {
                    $process = $botList[$token];
                    if ($process->isRunning()) {
                        //虚拟客户端已经运行
                        $message = json_encode(['event'=>'startup', 'state'=>'error','message'=>'虚拟客户端已经运行']);
                        $redis->hSet(Wework::BotTokenListHash, strtoupper(md5($token)), $message);
                    } else {
                        Log::bot("重启虚拟客户端：$token");
                        $process->restart();
                    }
                }
                $botList[$token] = $process;
            }
            usleep(250000);
        }
    }

//    private function _extractNewestOutput(Process $process): string
//    {
//        $output = $process->getOutput();
//        $cursor = empty($this->cursor[$process->token]) ? 0 : $this->cursor[$process->token];
//        $current = substr($output, $cursor);
//        $this->cursor[$process->token] = strlen($output);
//        return !empty($current) ? $current : '';
//    }

    private function _makeBotProcess(string $token): Process
    {
        $command = array_filter([
            $this->_phpBinary(),
            'think',
            'webot:worker',
            $token
        ], function ($value) {
            return !is_null($value);
        });
        return new Process($command, app()->getRootPath(), null, null, null);
    }

    private function _phpBinary()
    {
        return (new PhpExecutableFinder())->find(false);
    }
}